#![allow(dead_code)]
use prost::alloc::sync::Arc;
use wd_macro::ChainSet;
use std::thread;
use std::sync::atomic::{AtomicUsize, Ordering, AtomicBool};

use super::thread_channel::ThreadChanel;

pub trait ThreadTask{
    fn call(&self,_: &ThreadPool);
}

impl<T:Fn(&ThreadPool)> ThreadTask for T {
    fn call(&self, tp: &ThreadPool) {
        self(tp)
    }
}

#[derive(Clone,ChainSet)]
pub struct ThreadPool{
    pub status:Arc<AtomicBool>,
    running:Arc<AtomicUsize>, //运行中线程个数
    pub count:usize,
    handle:Arc<Box<dyn ThreadTask+Send+Sync+'static>>,
    chan:Arc<ThreadChanel>,
}

impl ThreadPool {
    pub fn build()->Self{
        let running = Arc::new(AtomicUsize::new(0));
        let count = 1;
        let handle:Arc<Box<dyn ThreadTask+Send+Sync+'static>> = Arc::new(Box::new(|_:&ThreadPool|{
            wd_log::log_debug_ln!("运行一个默认的任务");
        }));
        let chan =Arc::new(ThreadChanel::new());
        let status = Arc::new(AtomicBool::new(true));
        Self{status,running,count, handle,chan }
    }
    pub fn channel(&self) -> &Arc<ThreadChanel> {
        &self.chan
    }
    pub fn set_task<T:ThreadTask+Send+Sync+'static>(mut self, task:T)->Self{
        self.handle = Arc::new(Box::new(task));self
    }
    fn sub_running(&self){
        self.running.fetch_sub(1,Ordering::Relaxed);
    }
    fn add_running(&self){
        self.running.fetch_add(1,Ordering::Relaxed);
    }
    pub fn async_run(&self){
        self.start_work();
    }
    pub fn run(&self){
        self.start_work();
        loop {
            thread::sleep(std::time::Duration::from_millis(10));
            if self.running.load(Ordering::Relaxed) <= 0{
                break
            }
        }
    }
    fn start_work(&self){
        let mut i = 0;
        while i < self.count {
            i += 1;
            let thpool = self.clone();
            let task = self.handle.clone();
            thpool.add_running();
            thread::Builder::new().spawn(move||{
                task.call(&thpool);
                thpool.sub_running();
            }).unwrap();
        }
    }
}